#include <QPainter>
#include <QDebug>
#include "bullet.h"
#include "ca-pathfinding/grids/tile.h"
#include "ca-pathfinding/grids/grid.h"


Bullet::Bullet(Object* o)
{
    parent=o;
    grid=o->grid;
    tile=o->tile;
    purgatory=o->purgatory;
    type=ot::BULLET;
    friction=0.985;
    power=10.0f;
    speed=20.0f;
    alive=true;
}


void Bullet::purge()
{
    hide();
    purgatory->purge(this,type);
    alive=false;
}

void Bullet::control()
{
    if(parent->type==ot::OBJECTIVE)
    {
        if(distance(tile->x,tile->y,parent->tile->x,parent->tile->y)>=(static_cast<Objective*>(parent))->firing_range)speed=0;
    }
    else if(parent->type==ot::PLAYER)
    {
        if(distance(tile->x,tile->y,parent->tile->x,parent->tile->y)>=(static_cast<Player*>(parent))->firing_range)speed=0;
    }
}

void Bullet::physics()
{
    if(fabs(speed)<0.5)speed=0.0f;
    else speed*=friction;
}

void Bullet::step()
{
    translate(0,-speed);
    if(isColliding() || speed==0)
    {
        purge();
        return;
    }

    auto nbs=mn::neighbours(grid,tile->y/Tile::TILE_SIZE,tile->x/Tile::TILE_SIZE);
    float d1,d2,tx,ty,nx,ny;
    int eps=Tile::TILE_SIZE/5;
    for( auto n:nbs)
    {
        tx=tile->x-grid->width()*Tile::TILE_SIZE/2+Tile::TILE_SIZE/2;
        ty=tile->y-grid->height()*Tile::TILE_SIZE/2+Tile::TILE_SIZE/2;
        nx=n->x-grid->width()*Tile::TILE_SIZE/2+Tile::TILE_SIZE/2;
        ny=n->y-grid->height()*Tile::TILE_SIZE/2+Tile::TILE_SIZE/2;
        d1=distance(scenePos().x(),scenePos().y(),tx,ty);
        d2=distance(scenePos().x(),scenePos().y(),nx,ny);
        if(d1>d2 && abs(d1-d2)>eps) tile=n;

    }


}

bool Bullet::isColliding()
{

    if(parent!=grid->player && grid->player->tile==tile)
    {
        speed=0;
        grid->player->hit(power);
        return true;
    }


    for(Object* o:grid->objects[ot::WALL])
    {
        if(o!=parent && tile==o->tile)
        {
            speed=0;
            return true;
        }
    }
    for(Object* o:grid->objects[ot::OBJECTIVE])
    {
        if(o!=parent && tile==o->tile)
        {
            speed=0;
            static_cast<Objective*>(o)->hit(power*2);
            return true;
        }
    }

    return false;
}

void Bullet::paint(QPainter *painter, const QStyleOptionGraphicsItem *,QWidget *)
{
    painter->setBrush(Qt::black);
    painter->drawRect(boundingRect());
}

QRectF Bullet::boundingRect() const
{
    const static QRectF r(-5.0f,-15.0f,5.0f,15.0f);
    return r;

}
